'use strict';

/////////////////////////////////////////////////////////////////
Object.defineProperty(exports, '__esModule', { value: true });
/////////////////////////////////////////////////////////////////

var __importDefault =
  (this && this.__importDefault) ||
  function (mod) {
    return mod && mod.__esModule ? mod : { default: mod };
  };

const INTLIFY_BUNDLE_IMPORT_ID = '@vite-plugin-vue-i18n/messages';

exports.createI18nPlugin = void 0;
const defaultOpt = { includes: id => /type=i18n/i.test(id) };
const isString = val => typeof val === 'string';
const toTypeString = value => Object.prototype.toString(value);
const isPlainObject = val => toTypeString(val) === '[object Object]';
const isEmptyObject = val => isPlainObject(val) && Object.keys(val).length === 0;
const querystring_1 = __importDefault(require('querystring'));
function parseVueRequest(id) {
  const [filename, rawQuery] = id.split(`?`, 2);
  const query = querystring_1.default.parse(rawQuery);
  const langPart = Object.keys(query).find(key => /lang\./i.test(key));
  if (query.vue != null) {
    query.vue = true;
  }
  if (query.src != null) {
    query.src = true;
  }
  if (query.index != null) {
    query.index = Number(query.index);
  }
  if (query.raw != null) {
    query.raw = true;
  }
  if (langPart) {
    const [, lang] = langPart.split('.');
    query.lang = lang;
  }
  return {
    filename,
    query
  };
}

function isCustomBlock(query) {
  return !isEmptyObject(query) && 'vue' in query && (query['type'] === 'custom' || query['type'] === 'i18n' || query['blockType'] === 'i18n');
}

/**
 * Transform the code into assignment.
 *
 * @param varName the variable name.
 * @param code the code to transform.
 * @returns the transformed code.
 */
function transformCode(varName, code) {
  const assignmentPrefix = `const ${varName} =`;
  const codeTrimed = code.trim();
  if (codeTrimed.startsWith('{')) {
    return `${assignmentPrefix} ${codeTrimed};`;
  } else {
    return codeTrimed.replace(/export default/, assignmentPrefix);
  }
}

/**
 * Create the i18n plugin.
 *
 * @param opt the options.
 * @returns the i18n plugin.
 */
function createI18nPlugin(options) {
  const yaml = require('js-yaml');
  const opts = Object.assign({}, defaultOpt, options);
  return {
    name: 'vite-plugin-vue2-i18n',
    resolveId(id) {
      if (id === INTLIFY_BUNDLE_IMPORT_ID) {
        return id;
      }
    },
    async load(id) {
      if (id === INTLIFY_BUNDLE_IMPORT_ID) {
        // 这里未来可以支持多语言，暂时只做演示
        return `export const messages = {};`;
      }
    },
    async handleHotUpdate({ file, server }) {
      if (/\.(json5?|ya?ml)$/.test(file)) {
        const module = server.moduleGraph.getModuleById(INTLIFY_BUNDLE_IMPORT_ID);
        if (module) {
          server.moduleGraph.invalidateModule(module);
          return [module];
        }
      }
    },
    transform(code, id) {
      if (!opts.includes(id) && /\.y(a)?ml$/i.test(id)) {
        code = JSON.stringify(yaml.load(code.trim()));
        return {
          code: transformCode('__yaml', code) + `export default __yaml`,
          map: {
            mappings: ''
          }
        };
      }

      if (opts.includes(id)) {
        const { query } = parseVueRequest(id);
        if (isCustomBlock(query)) {
          if (['yaml', 'yml'].includes(query.lang)) {
            code = JSON.stringify(yaml.load(code.trim()));
          }

          const locale = isString(query.locale) ? query.locale : '';
          if (locale) {
            code = `{"${locale}": ${code.trim()}}`;
          } else {
            code = code.trim();
          }
        }

        return {
          code:
            transformCode('__i18n', code) +
            `export default function i18n(Component) {\n` +
            `  const options = Component.options || Component\n` +
            `  options.__i18n = options.__i18n || []\n` +
            `  options.__i18n.push(JSON.stringify(__i18n))\n` +
            `}`,
          map: {
            mappings: ''
          }
        };
      }
    }
  };
}

exports.createI18nPlugin = createI18nPlugin;
